<?php

namespace App\Models;

use App\Exceptions\Arr;
use Dcat\Admin\Traits\HasDateTimeFormatter;

use Illuminate\Database\Eloquent\Model;
use Illuminate\Support\Facades\DB;

class AppointNum extends Model
{
	use HasDateTimeFormatter;
    protected $table = 'eb_appoint_num';
    public static function booted()
    {
        parent::booted();
        static::creating(function ($model){
            $week = date('w',strtotime($model->appoint_date));
            $model->week = $week;
            if(empty($model->project)){
                $model->project = 0;
            }
            if(empty($model->street_id)){
                $model->street_id = 0;
            }
        });
        static::updating(function ($model){
            $week = date('w',strtotime($model->appoint_date));
            $model->week = $week;
            if(empty($model->project)){
                $model->project = 0;
            }
            if(empty($model->street_id)){
                $model->street_id = 0;
            }
        });
    }

    public static function SetupScheduling($hospitalAppointId,$day=false,$test=false)
    {

        $ws = [
            '1' => '周一  ',
            '2' => '周二  ',
            '3' => '周三  ',
            '4' => '周四  ',
            '5' => '周五  ',
            '6' => '周六  ',
            '0' => '周日  ',
        ];
        $appointMax = new AppointNum();
        $hospitalAppoint = HospitalAppoint::query()->where('id',$hospitalAppointId)->first();
        if(!$hospitalAppoint)
            throw new \Exception("初始化失败，预约设置不存在");

        if($hospitalAppoint->is_open==0)
            throw new \Exception("初始化失败，预约设置未开启");
        $weeks = json_decode($hospitalAppoint->weeks);

        $intervals = HospitalAppointInterval::query()
            ->where('hospital_appoint_id', $hospitalAppointId)
            ->get();
        if (!$intervals)
            throw new \Exception("初始化失败，未设置时间段");

        $intervalNum = HospitalAppointIntervalNum::query()
            ->where('hospital_appoint_id', $hospitalAppointId)
            ->sum('num');
        if ($intervalNum<=0)
            throw new \Exception("初始化失败，未设置基础号源");
        $cycle = $hospitalAppoint->cycle;
        $extend_day = $hospitalAppoint->extend_day;//周期外可查看天数
        $non_date = json_decode($hospitalAppoint->non_date,true);
        $sure_date = json_decode($hospitalAppoint->sure_date,true);

        //获取街道设置
        $streetModel = HospitalAppointStreet::query()->where('hospital_appoint_id', $hospitalAppointId)->first();
        if ($streetModel) {
            $streetSetup = json_decode($streetModel->street, true);
            if(array_filter($streetSetup)) {
                foreach ($weeks as $wv) {
                    if (!$streetSetup['week' . $wv]) {
                        throw new \Exception("初始化失败，{$ws[$wv]}未设置街道");
                    }
                }
            }
        }



        $dataRow = [];
        $dates = '<br> 初始化日期：';
        //生成基础设置
        if($day){
            $j = $cycle+$extend_day;
            $ja = $cycle+$extend_day+1;
        }else{
            $j = 0;
            $ja = $cycle+$extend_day;
        }
        for($i=$j;$i<$ja;$i++) {
            $delay = $hospitalAppoint->delay + $i + 1;
            $dateTime = strtotime('+' . $delay . ' day');
            $date = date('Y-m-d', $dateTime);

            $appoint = Appoint::query()->where([
                'hospital_id'=>$hospitalAppoint->hospital_id,
                'type'=>$hospitalAppoint->type,
                'appoint_date'=>$date,
            ])
                ->whereIn('status',[1,6])
                ->count();
            if($appoint > 0){
                $dates .= "<br>".$date."已存在预约";
                continue;
                //已存在预约跳过初始化
            }
            //删除排班
            $appointMax->query()
                ->where('hospital_id', $hospitalAppoint->hospital_id)
                ->where('appoint_type', $hospitalAppoint->type)
                ->where('date',$date)
                ->delete();

            //判断节假日
            $hospitalAppointHoliday = HospitalAppointHoliday::query()
                ->where('date',$date)
                ->whereIn('hospital_id',[0,$hospitalAppoint->hospital_id])
                ->whereIn('hospital_appoint_id',[0,$hospitalAppoint->id])
                ->first();
            if($hospitalAppointHoliday){
                $dates .= "<br>".$date."节假日";
                continue;
            }
            //社区设置不可约日期
            if(in_array($date,$non_date)) {
                $dates .= "<br>".$date."社区设置不可约";
                continue;
            }
            $week = date('w', $dateTime);
            if(!in_array($week, $weeks) && !in_array($date,$sure_date)) {
                $dates .= "<br>".$date."非门诊日";
                continue;
            }



            $data = [];
            $data['date'] = $date;
            $data['week'] = $week;
            $data['appoint_type'] = $hospitalAppoint->type;
            $data['hospital_id'] = $hospitalAppoint->hospital_id;

            foreach ($intervals as $interval) {
                $intervalNum = HospitalAppointIntervalNum::query()
                    ->where('hospital_appoint_id', $hospitalAppointId)
                    ->where('interval_id', $interval->id)
                    ->where('week', $week)
                    ->first();
                if (!isset($intervalNum) || $intervalNum->num == 0)
                    continue;
                $data['interval_id'] = $interval->id;
                $data['interval_num'] = $intervalNum->num;
                $data['project_num'] = -1;
                $data['project_interval_num'] = -1;
                if(isset($streetSetup)) {
                    if(!Arr::collapse($streetSetup)) {
                        $dataRow[] = $data;
                        continue;
                    }
                    if (isset($streetSetup['week' . $week])) {
                        foreach ($streetSetup['week' . $week] as $k => $v) {
                            $streetData = $data;
                            $streetData['street_id'] = $v;
                            //$appointMax->query()->insert($streetData);
                            $dataRow[] = $streetData;
                        }
                    }
                }else{
                    $dataRow[] = $data;
                }
            }
            $dates .= "<br>".$date."成功";

        }
        $insertData = $dataRow;
        //生成结束
        if(in_array($hospitalAppoint->type,[2,13])){
            $hospitalAppointVaccine = HospitalAppointVaccine::query()
                ->where('hospital_appoint_id',$hospitalAppointId)
                ->get();
            if($hospitalAppointVaccine->toArray()) {
                $intervalRow = [];
                foreach ($hospitalAppointVaccine as $v) {
                    $vaccineWeeks = json_decode($v->weeks,true);
                    $weekNum = json_decode($v->week_num, true);
                    $intervalNum = json_decode($v->interval_num, true);


                    if(!array_intersect($vaccineWeeks,$weeks)){
                        $vaccine = Vaccine::query()->where('id',$v->vaccine_id)->first();
                        throw new \Exception("初始化失败，{$vaccine->name} 不在门诊日范围内");
                    }


                    foreach ($dataRow as $dv) {
                        if(!in_array($dv['week'], $vaccineWeeks))
                            continue;
                        $row = $dv;
                        $row['project'] = $v->vaccine_id;
                        if (isset($weekNum['week' . $dv['week']])) {
                            $row['project_num'] = $weekNum['week' . $dv['week']];
                        } else {
                            $row['project_num'] = -1;
                        }
                        $dvInterval_id = $dv['interval_id'];
                        $dvWeek = $dv['week'];
                        if($intervalNum) {
                            $filteredRow = Arr::collapse(array_filter($intervalNum, function ($where) use ($dvInterval_id, $dvWeek) {
                                return $where['week'] == $dvWeek && $where['interval_id'] == $dvInterval_id;
                            }));
                            if ($filteredRow && $filteredRow['open'] == 1) {
                                $row['project_interval_num'] = $filteredRow['num'] == "" ? -1 : $filteredRow['num'];
                            } else {
                                //如果未勾选则跳过，不生成排班
                                continue;
                                //$row['project_interval_num'] = 0;
                            }
                        }else{
                            //如果未设置按照时间段分配疫苗则表示无限制
                            $row['project_interval_num'] = -1;
                        }
                        $intervalRow[] = $row;
                    }
                }
                $insertData = $intervalRow;
            }
        }
        //DB::transaction(function () use($insertData,$appointMax){
        if(!$test) {
            foreach ($insertData as $k => $v) {
                    $appointMax->query()->insert($v);
            }
        }
        //});

        return $date;
    }
}
